// CS U213 Spring 2009
// WorldDemo.java sample program
// Shows how to use the World class to produce an interactive game
// October 8, 2008

import draw.*;
import colors.*;
import geometry.*;

//                     
//                     
//  ** *               
// *  **               
// *     **  ** ** **  
//  ***   *   *  **  * 
//     *  *   *  *   * 
//     *  *   *  *   * 
// **  *  *  **  *   * 
// * **    ** ***** ***
//                     
//                     
//                     
//                     

// the only objects in our game: a sun that grows or shrinks
class Sun{
  int size;
  
  Sun(int size){
    this.size = size; 
  }
  
  // draw this sun on the given Canvas
  boolean drawSun(Canvas c){
    return c.drawDisk(new Posn(50, 50), this.size, new Red());
  }
  
  // produce a bigger sun as the time ticks
  Sun onTick(){
    return new Sun(this.size + 2);
  }
  
  // decrease the size of the sun when "d" is pressed
  // increase when "i" is pressed
  Sun onKeyEvent(String ke){
    if (ke.equals("d")){              // decrease the radius of the circle
      return new Sun(this.size - 3);}
    else {if (ke.equals("i")){        // increase the radius of the circle
      return new Sun(this.size + 3);}
    else {
      return this;}}
  }  
  
  // the sun dies when its size is 3 or less
  boolean isDead(){
    return this.size <= 3;
  }
}

//                                                               
//                                                               
//*** ***   *             *   *** ***                **       ** 
// ** **                       *   *                  *        * 
// ** **  ***   ** **   ***    *   *   ***   ** **    *     ** * 
// * * *    *    **  *    *    * * *  *   *   **      *    *  ** 
// * * *    *    *   *    *    * * *  *   *   *       *    *   * 
// *   *    *    *   *    *    * * *  *   *   *       *    *   * 
// *   *    *    *   *    *    * * *  *   *   *       *    *   * 
//*** *** ***** *** *** *****   * *    ***   *****  *****   *****
//                                                               
//                                                               
//                                                               
//                                                               

// a class to represent a world with one dying red sun
class MiniWorld extends World{
  Sun s;

  MiniWorld(Sun s){
    this.s = s;
  }

  // start the world and the timer
  boolean go() { return this.bigBang(100,100,1.0); }
 
  // make the world grow with the timer
  // stop the world if the sun is dead
  World onTick() { 
    if (this.s.isDead()){
      return this.endOfWorld("The sun died!");
    }
    else{
      return new MiniWorld(this.s.onTick()); 
    }
  }

  // decrease the size of the sun when "d" is pressed
  // stop the world if the sun is dead
  World onKeyEvent(String ke) { 
    if (this.s.isDead()){
      return this.endOfWorld("The sun died!");
    }
    else{
      return new MiniWorld(this.s.onKeyEvent(ke));
    }
  }

  // draw the sun
  boolean draw(){
    return this.s.drawSun(this.theCanvas);
  }
}

//                                                        
//                                                        
//******                               **                 
// *   *                                *                 
// * *   **  **   ***  *** *  ** **     *     ***    **** 
// ***    *  *   *   *  * * *  **  *    *    *   *  *   * 
// * *     **     ****  * * *  *   *    *    *****   ***  
// *       **    *   *  * * *  *   *    *    *          * 
// *   *  *  *   *   *  * * *  *   *    *    *      *   * 
//****** **  **   ************ ****   *****   ****  ****  
//                             *                          
//                            ***                         
//                                                        
//                                                        

// examples and tests for the miniworld with a sun
class Examples{
  Examples() {}

  // define a new sun and a new world
  Sun s30 = new Sun(30);
  Sun deadSun = new Sun(2);
  MiniWorld mw = new MiniWorld(this.s30);

  // test the method onTick in the class Sun
  boolean testOnTickSun = 
    check this.s30.onTick() expect new Sun(32);
    
  // test the method onKeyEvent in the class Sun
  boolean testOnKeyEventSun = 
    (check this.s30.onKeyEvent("x") expect this.s30) &&
    (check this.s30.onKeyEvent("d") expect new Sun(27)) &&
    (check this.s30.onKeyEvent("i") expect new Sun(33)) &&
    (check this.s30.onKeyEvent("left") expect this.s30);

  // test the method isDead in the class Sun
  boolean testIsDeadSun = 
    (check this.s30.isDead() expect false) &&
    (check this.deadSun.isDead() expect true);
    
  Canvas c = new Canvas(100, 100);
  boolean testDrawSun = 
    c.show() &&
    this.s30.drawSun(this.c);

  // test the method onTick in the class MiniWorld
  boolean testOnTick = 
    check this.mw.onTick() expect new MiniWorld(new Sun(32));

  // test the method onKeyEvent in the class MiniWorld
  boolean testOnKeyEvent = 
    (check this.mw.onKeyEvent("x") expect this.mw) &&
    (check this.mw.onKeyEvent("d") expect new MiniWorld(new Sun(27))) &&
    (check this.mw.onKeyEvent("i") expect new MiniWorld(new Sun(33))) &&
    (check this.mw.onKeyEvent("left") expect this.mw);
  
  // start our world --- by displaying the canvas, 
  //                     starting the timer
  //                     and responding to key events
  boolean run = this.mw.go();
}